#!/usr/bin/python

# Copyright 2006-2008 Hewlett-Packard Development Company, L.P.
# HP Confidential.  No photocopying.  SCons rocks.

# Author: Tim Potter <tpot@hp.com>

#
# A small utility to wrap up a PyWBEM session in a Python interactive
# console.
#
# Usage: 
#
#   wbemcli.py HOSTNAME [-u USERNAME -p PASSWORD] [-n namespace] [--no-ssl] \
#       [--port PORT]
#
# CIM operations can be executed by using the PyWBEM connection object
# called 'cli' in the global scope.  There are two sets of aliases
# available for usage in the interpreter. For example the following
# three commands are equivalent:
#
#   >>> cli.EnumerateInstanceNames('SMX_ComputerSystem')
#   >>> EnumerateInstanceNames('SMX_ComputerSystem')
#   >>> ein('SMX_ComputerSystem')
#
# Pretty-printing of results is also available using the 'pp'
# function. For example:
#
#   >>> cs = ei('SMX_ComputerSystem')[0]
#   >>> pp(cs.items())
#   [(u'RequestedState', 12L),
#    (u'Dedicated', [1L]),
#    (u'StatusDescriptions', [u'System is Functional']),
#    (u'IdentifyingNumber', u'6F880AA1-F4F5-11D5-8C45-C0116FBAE02A'),
#   ...
#

#
# Nov,2009: Extend wbemcli.py with command line support.
#

import os, stat, sys, string, getpass, errno
from pywbem import *
from code import InteractiveConsole
from optparse import OptionParser
from random import random
from pprint import pprint as pp

from time import *
from datetime import *
from xml.dom.minidom import parse, parseString

# Conditional support of readline module

have_readline = False

try:
    import readline
    have_readline = True
except ImportError, arg:
    pass

class Callable:
    def __init__(self, anycallable):
        self.__call__ = anycallable


#
# Parse command line args
#
class WBEMCommandLine:
    def  __init__(self):
        self.InitVariables()
        self.NewOptionParser()
        self.CheckCommands()
        
    def InitVariables(self):
        self.cmds_dict = {
            'ein' : 'Enumerate Instance Names',
            'ei' : 'Enumerate Instances',
            'gi' : 'Get Instance',
            'di' : 'Delete Instance',
            'mi' : 'Modify Instance',
            'ci' : 'Create Instance',
            'im' : 'Invoke Method',
            'an' : 'Associator Names',
            'ao' : 'Associators',
            'rn' : 'Reference Names',
            're' : 'References',
            'ecn' : 'Enumerate ClassNames',
            'ec' : 'Enumerate Classes',
            'gc' : 'Get Class',
            'dc' : 'Delete Class',
            'mc' : 'Modify Class',
            'cc' : 'Create Class',
            'eq' : 'Enumerate Qualifiers',
            'gq' : 'Get Qualifier',
            'sq' : 'Set Qualifier',
            'dq' : 'Delete Qualifier',
            'lsac' : 'LiSt All Classes',
            'lsic' : 'LiSt Implemented Classes',
            'lsps' : 'LiSt Providers Status',
            'lspc' : 'LiSt Providers and Classes they implemented'}
            
        self.param_dict = {
            'ein': 'ClassName',
            'ei' : 'ClassName',
            'gi' : 'InstanceName',
            'di' : 'InstanceName',
            'mi' : 'InstanceName',
            'ci' : 'InstanceName',
            'im' : 'MethodName',
            'an' : 'AssociatorName',
            'ao' : 'AssociatorName',
            'rn' : 'ReferenceName',
            're' : 'ReferenceName',
            'ecn':  None,
            'ec' :  None,
            'gc' : 'ClassName',
            'dc' : 'ClassName',
            'mc' : 'ClassName',
            'cc' : 'ClassName',
            'eq' : 'QualifierName',
            'gq' : 'QualifierName',
            'sq' : 'QualifierName',
            'dq' : 'QualifierName',
            'lsac' : None,
            'lsic' : None,
            'lsps' : None,
            'lspc' : None}
            
        self.all_cmds = ['ein', 'ei', 'gi', 'di', 'mi', 'ci', 'im', 'an', 'ao', 'rn', 're', 'ecn', 'ec', 'gc', 'dc', 'mc', 'cc', 'eq', 'gq', 'sq', 'dq']
        self.imp_cmds = ['ein', 'ei', 'an', 'ao', 'rn', 're', 'ecn', 'ec', 'gc', 'eq', 'lsac', 'lsic', 'lsps', 'lspc']
        
        self.usage = '%prog HOSTNAME [-u USER -p PASS] [-n NAMESPACE] [--no-ssl]'
        self.cmds_help = ''
        for imp_cmd in self.imp_cmds:
            self.cmds_help = self.cmds_help + '|--' + imp_cmd
        self.cmds_help = ' [' + self.cmds_help[1:] + '] '
        self.usage = self.usage + self.cmds_help + '[VALUE] [-h|--help]'
    
    def NewOptionParser(self):
        self.optparser = OptionParser( usage = self.usage )
        
        # Host, username and password
        self.optparser.add_option('-u', '--user', dest = 'user',
                             action = 'store', type = 'string', default = "root",
                             help = 'user to connect as')
        self.optparser.add_option('-p', '--password', dest = 'password',
                             action = 'store', type = 'string', default = "iforgot",
                             help = 'password to connect user as')
                             
        # Change the default namespace used #'root/cimv2'
        self.optparser.add_option('-n', '--namespace', dest = 'namespace',
                             action = 'store', type = 'string', default = 'root/hpq', 
                             help = 'default namespace to use')
        # Don't use SSL for remote connections
        self.optparser.add_option('--no-ssl', dest = 'no_ssl', action = 'store_true',
                             help = 'don\'t use SSL')
                             
        # Specify non-standard port
        self.optparser.add_option('--port', dest = 'port', action = 'store', type = 'int',
                             help = 'port to connect as', default = None)
                             
        # Add WBEM commands
        for imp_cmd in self.imp_cmds:
            msg = 'WBEM: ' + self.cmds_dict[imp_cmd]
            if self.param_dict[imp_cmd] != None:
                msg = msg + ' (VALUE = ' + self.param_dict[imp_cmd] + ')'
            self.optparser.add_option('--' + imp_cmd, dest = imp_cmd, 
                                      action = 'store_true', help = msg )

    def CheckCommands(self):
        (opts, argv)   = self.optparser.parse_args()

        self.user      = opts.user
        self.password  = opts.password
        self.namespace = opts.namespace
        self.no_ssl    = opts.no_ssl
        self.port      = opts.port
        self.host      = "localhost"
        self.command   = None
        self.param     = None
        
        if len(argv) >= 1:
            self.host  = argv[0]
        if len(argv) >= 2:
            self.param = argv[1]
        if len(argv) <  1:
            self.optparser.print_usage()
            sys.exit(1)
            
        for imp_cmd in self.imp_cmds:
            if opts.__dict__.has_key(imp_cmd):
                if opts.__dict__[imp_cmd] != None:
                    self.command = imp_cmd
                    break

        if self.command == None :
            self.interactive = True
            if os.system('ping '+ self.host +' -c 1 >/dev/null 2>&1') != 0:
                print "( %s ) does not seems to be a host name" % self.host
                sys.exit(1)
        else:
            self.interactive = False
            if self.param_dict[self.command] != None and self.param == None:
                print "--%s need a param (VALUE = %s)" % (self.command, self.param_dict[self.command])
                sys.exit(1)


#
# Set up a client connection
#
class WBEMClient:
    def  __init__(self, wcl):
        self.wbemcmd = wcl
        self.conn = self._remote_connection()
        
    def _local_connection(self):
        """Return a PyWBEM connection to run tests on."""
        
        if os.access('/tmp/sfcbHttpSocket', os.F_OK):
            return SFCBUDSConnection()
            
        elif os.access('/var/run/tog-pegasus/cimxml.socket', os.F_OK):
            return PegasusUDSConnection()
            
        raise RuntimeError('Unable to detect CIMOM type for local connection')
        
    def _remote_connection(self):
        """Initiate a remote connection, via PyWBEM."""

        if self.wbemcmd.host[0] == '/':
            url = self.wbemcmd.host
        else:
            proto = 'https'
    
            if self.wbemcmd.no_ssl:
                proto = 'http'
    
            url = '%s://%s' % (proto, self.wbemcmd.host)
    
            if self.wbemcmd.port is not None:
                url += ':%d' % self.wbemcmd.port
    
        creds = None
    
        if self.wbemcmd.user is not None and self.wbemcmd.password is None:
            self.wbemcmd.password = getpass.getpass('Enter password for %s: ' % self.wbemcmd.user)
    
        if self.wbemcmd.user is not None or self.wbemcmd.password is not None:
            creds = (self.wbemcmd.user, self.wbemcmd.password)
    
        cli = WBEMConnection(url, creds, default_namespace = self.wbemcmd.namespace)
    
        cli.debug = True

        return cli

#
# Called by WBEMPrint for format output
#
class WBEMGet:
    def _property( obj, key ):
        ret = None
        if ( obj is None ):
            return ret
        try:
            if ( obj.has_key( key ) ):
                return obj[key]
        except AttributeError:
            ret = None
        try:
            if ( obj.__dict__.has_key( key ) ):
                return obj.__dict__[key]
        except AttributeError:
            ret = None
        return ret
    _property = Callable( _property )
    
    def _inst_prop( inst, instname ):
        for name,value in inst.items():
              if ( name == instname ):
                return value
        return None
    _inst_prop = Callable( _inst_prop )
    
    def _type( obj ):
        obj_type = WBEMGet._property( obj, "type" )
        is_array = WBEMGet._property( obj, "is_array" )
        if ( is_array is None ):
            is_array = False
        if ( obj_type is None ):
            obj_type = "%s" % obj.__class__.__name__
        if ( is_array ):
            obj_type = "<%s[]>" % obj_type
        else:
            obj_type = "<%s>" % obj_type
        return obj_type
    _type = Callable( _type )
    
    def _value( obj ):
        if type(obj).__name__ == "CIMProperty" or type(obj).__name__ == "CIMQualifier":
            obj_value = WBEMGet._property( obj, "value" )
        else:
            obj_value = "%s" % (str(obj))
        return obj_value
    _value = Callable( _value )
    

#
# Format output for wbem class items/properties
#
class WBEMPrint:
    def _items( pair_list , prefix ):
        if type(pair_list) != list or len(pair_list) == 0 :
            return
        for key,obj in pair_list:
            WBEMPrint._object( key,obj, prefix )
    _items = Callable( _items )
    
    def _object( name, obj, prefix ):
        prefix = "    %s" % prefix;
        pyclass = type(obj).__name__
        pair_list = None
        
        if pyclass == "CIMInstanceName" or pyclass == "CIMInstance" or pyclass == "CIMClass" or pyclass == "CIMMethod" or pyclass == "CIMParameter":
            pair_list = obj.__dict__.items()
            
        if pyclass == "NocaseDict" or pyclass == "dict":
            pair_list = obj.items() 
            
        if ( pair_list != None ):
            print "%s%s %s:" % ( prefix, WBEMGet._type(obj), name )
            WBEMPrint._items( pair_list, prefix)
            return
        
        print '%s%-12s %-25s = %s' % ( prefix, WBEMGet._type(obj), name, WBEMGet._value ( obj ) )
    _object = Callable( _object )
    
    def _instance( obj ):
        print obj.path
        #_object("path", obj.path, "")
        WBEMPrint._items( obj.properties.items(), "" )
        WBEMPrint._items( obj.qualifiers.items(), "" )
        print ""
    _instance = Callable( _instance )
    
    def _qualifier( obj ):
        print "%s %s:" % ( WBEMGet._type(obj), WBEMGet._property(obj, "name" ) )
        WBEMPrint._items( obj.scopes.items(), "" )
        print ""
    _qualifier = Callable( _qualifier )

    def _class( obj ):
        print "\n<%s>:" % ( WBEMGet._property( obj, "classname" ) )
        WBEMPrint._object( "superclass", obj.superclass, "" )
        print "    <NocaseDict> properties"
        WBEMPrint._items( obj.properties.items(), "    " )
        print "    <NocaseDict> methods:"
        WBEMPrint._items( obj.methods.items(), "    " )
        print "    <NocaseDict> qualifiers:"
        WBEMPrint._items( obj.qualifiers.items(), "    " )
    _class = Callable( _class )
    
    def _list( lst ):
        for obj in lst:
            print ""
            print obj
            WBEMPrint._items( obj.__dict__.items(), "" )
    _list = Callable( _list )

#
# Handle all kinds of wbemcli commands
#
class WBEMHandler:
    def  __init__(self, wcmd, wclient):
        self.cmds = wcmd
        self.wbem = wclient
        self.all_handlers = [ self._handler_ein, 
                              self._handler_ei,
                              self._handler_gi,
                              self._handler_ec,
                              self._handler_ecn,
                              self._handler_gc,
                              self._handler_eq,
                              self._handler_an,
                              self._handler_ao,
                              self._handler_rn,
                              self._handler_re,
                              self._handler_lsac,
                              self._handler_lsic,
                              self._handler_lsps,
                              self._handler_lspc,
                              self._handler_help ]
    
    def _execute(self):
        for handler in self.all_handlers:
            handler( self.cmds.command, self.cmds.param,  self.cmds.namespace)

    def _print_start( self, msg = "" , step = 1):
        self._printStep = step
        self._printCount = 0
        sys.stdout.write("%s["%msg)
        sys.stdout.flush()
        
    def _print_process(self):
        if ( self._printCount % self._printStep == 0 ):
            sys.stdout.write('.')
            sys.stdout.flush()
        self._printCount = self._printCount + 1
        
    def _print_end(self):
        sys.stdout.write(']\n')
        sys.stdout.flush()
    
    def _handler_ein ( self, command, param, namespace ):
        if command != 'ein':
            return
        if param is None:
            sys.exit(1)
        results = self.wbem.conn.EnumerateInstanceNames( param, namespace =  namespace)
        print ""
        for obj in results:
            print obj
        print ""
        
    
    def _handler_ei ( self, command, param, namespace ):
        if command != 'ei':
            return
        if param is None:
            sys.exit(1)
        results = self.wbem.conn.EnumerateInstances(param, namespace = namespace, DeepInheritance = True, IncludeQualifiers = False, IncludeClassOrigin = False)
        print ""
        for obj in results:
            WBEMPrint._instance(obj)
            #print obj
        print ""
        
    
    def _handler_gi ( self, command, param, namespace ):
        if command != 'gi':
            return
        if param is None:
            sys.exit(1)
        results = self.wbem.conn.GetInstance( CIMInstanceName( classname = param, host = self.cmds.host, namespace = namespace ) )
        _instance(results)
        #print obj


    def _handler_ecn ( self, command, param, namespace ):
        if command != 'ecn':
            return
        results = self.wbem.conn.EnumerateClassNames( namespace = namespace )
        print ""
        for obj in results:
            print obj
        print ""
                    
                    
    def _handler_ec ( self, command, param, namespace ):
        if command != 'ec':
            return
        results = self.wbem.conn.EnumerateClasses( namespace = namespace )
        print ""
        for obj in results:
            WBEMPrint._class(obj)
            #print obj
        print ""
            
            
    def _handler_gc ( self, command, param, namespace ):
        if command != 'gc':
            return
        if param is None:
            sys.exit(1)
        results = self.wbem.conn.GetClass( param )
        WBEMPrint._class(results)
            
            
    def _handler_eq ( self, command, param, namespace ):
        if command != 'eq':
            return
        results = self.wbem.conn.EnumerateQualifiers( namespace = namespace )
        print ""
        for obj in results:
            #_qualifier( obj )
            print obj
        print ""
     
     
    def _handler_an ( self, command, param, namespace ):
        if command != 'an':
            return
        if param is None:
            sys.exit(1)
        results = self.wbem.conn.AssociatorNames(param)
        print ""
        for obj in results:
            print obj
        print ""
            
            
    def _handler_ao ( self, command, param, namespace ):
        if command != 'ao':
            return
        if param is None:
            sys.exit(1)
        results = self.wbem.conn.Associators(param)
        print ""
        for obj in results:
            print obj[0]
            WBEMPrint._object( "", obj[1], "" )
            print ""
        print ""
            
            
    def _handler_rn ( self, command, param, namespace ):
        if command != 'rn':
            return
        if param is None:
            sys.exit(1)
        results = self.wbem.conn.ReferenceNames(param)
        print ""
        for obj in results:
            print obj
        print ""
            
            
    def _handler_re ( self, command, param, namespace ):
        if command != 're':
            return
        if param is None:
            sys.exit(1)
        results = self.wbem.conn.References(param)
        print ""
        for obj in results:
            print obj[0]
            WBEMPrint._object( "", obj[1], "" )
            print ""
        print ""

    def check_related_classes(self, class_name):
        anlst = self.wbem.conn.AssociatorNames(class_name)
        for rc in anlst:
            if rc.classname not in self.checked_classes:
                #sys.stdout.write('.')
                #sys.stdout.flush()
                print rc.classname
                self.checked_classes.append( rc.classname )
                self.check_related_classes( rc.classname )
            

    def _handler_lsic ( self, command, param, namespace ):
        if command != 'lsic':
            return
        self.checked_classes = []
        # Get all class first
        #sys.stdout.write ( "Iterating all classes, please stand by:\n" )
        #sys.stdout.flush()
        self.check_related_classes( 'SMX_ComputerSystem' )
        #sys.stdout.write ( '\n\n' )
        #sys.stdout.flush()

    def _handler_lsac ( self, command, param, namespace ):
        if command != 'lsac':
            return
        
        self._print_start("")
        repodir = "/var/lib/Pegasus/repository/root#hpq/classes/"
        files = os.listdir( repodir )
        
        self._print_process()
        # Fetch all class files
        relalist = []
        for f in files:
            name = "%s" %f
            try:
                child,parent = name.split(".")
            except ValueError:
                continue
            relalist.append( (child, parent) )
        
        # Build Class Tree
        sortlist = []
        while ( len(relalist) > 0 ):
            self._print_process()
            lastcnt = len(relalist)
            for (child,parent) in relalist:
                if ( parent == '#') :
                    sortlist.append( child )
                    relalist.remove( (child,parent) )
                    continue
                for name in sortlist:
                    namelist = name.split(".")
                    lastname = namelist[len(namelist)-1]
                    if (lastname == parent):
                        newname = name+"."+child
                        sortlist.append( newname  )
                        relalist.remove( (child,parent) )
            # If can not move any thing to new list, stop linking
            if (len(relalist) == lastcnt):
                break;
        sortlist.sort()
        self._print_end()
        
        # Make the final print list
        finalist = []
        for name in sortlist:
            parts = name.split(".")
            leading = ""
            for i in range(0, len(parts)-1):
                leading = leading + "  "
            print "%s%s" % (leading, parts[len(parts)-1])
        print relalist
        # self.checked_classes = []
        # self.check_related_classes( 'SMX_ComputerSystem' )


    def _conv_secs(self, elapsedTime):
        secsInMin=60
        secsInHour=3600
        secsInDay=secsInHour*24
        daysUp=elapsedTime/secsInDay
        hoursUp=(elapsedTime - ( daysUp * secsInDay)) / secsInHour;
        minUp=(elapsedTime - ( daysUp * secsInDay) - ( hoursUp * secsInHour) ) / secsInMin;
        secsUp=elapsedTime - ( daysUp * secsInDay) - ( hoursUp * secsInHour) - ( minUp * secsInMin);
        if ( daysUp == 0 ) :
            return  "%02d:%02d:%02d" % (hoursUp, minUp, secsUp)
        else :
            return "%02d#%02d:%02d:%02d" % (daysUp, hoursUp, minUp, secsUp)


    def _handler_lsps ( self, command, param, namespace ):
        if command != 'lsps':
            return
        param = 'SMX_ExecutiveStatus'
        namespace = 'root/hpq'
        results = self.wbem.conn.EnumerateInstances(param, namespace = namespace, DeepInheritance = True, IncludeQualifiers = False, IncludeClassOrigin = False)
        for obj in results:
            # print "StartupStatus = (%s), IsRunning = (%s), %s" % (WBEMGet._property(obj, 'StartupStatus'), WBEMGet._property(obj, 'IsRunning'), datetime.now())
            startUpTime = WBEMGet._property(obj, 'StartupTime')
            # print 'Total Startup Time               : %d (us)' % (startUpTime)
            elapsedTime = WBEMGet._property(obj, 'ElapsedTimeRunning')
            #print 'Total Elapsed Time :',self._conv_secs( elapsedTime )
            
            providers = WBEMGet._property(obj, 'WorkerProviderName')
            lcl = WBEMGet._property(obj, 'WorkerLastCall')
            ctl = WBEMGet._property(obj, 'WorkerPollInterval')
            passcnt = WBEMGet._property(obj, 'WorkerPassStatusCount')
            failcnt = WBEMGet._property(obj, 'WorkerFailStatusCount')
            excpcnt = WBEMGet._property(obj, 'WorkerExceptionCount')
            wltl = WBEMGet._property(obj, 'WorkerLastTime')
            wmtl = WBEMGet._property(obj, 'WorkerMaxTime')
            print "##/##=WorkerLastCall/WorkerPollInterval; P=WorkerPassStatusCount; F=WorkerFailStatusCount; X=WorkerExceptionCount; LT=WorkerLastTime; MX=WorkerMaxTime. "
            print "---------------------------------------------------------------------"
            for i in range(0, len(providers)):
                print "%-20s    (%02d/%02d, P:%d,F:%d,X:%d, LT:%s,MX:%s)" % (providers[i], 
                                                                     lcl[i], ctl[i],
                                                                     passcnt[i], failcnt[i], excpcnt[i],
                                                                     self._conv_secs(wltl[i]/1000), self._conv_secs(wmtl[i]/1000))

    def _handler_lspc ( self, command, param, namespace ):
        if command != 'lspc':
            return
        
        self._print_start()
        # Make a xml compact file, since the org file is not a valid xml file
        instfn = "/var/lib/Pegasus/repository/root#PG_InterOp/instances/PG_ProviderCapabilities.instances"
        modfn = instfn + ".mod"
        instf = open( instfn, "r")
        modf = open( modfn, "w")
        modf.write("<ROOT>\n")
        for line in instf.readlines():
            modf.write(line)
        modf.write("</ROOT>\n")
        instf.close()
        modf.close()
        self._print_process()
        
        # Paser modified xml file
        dom = parse( modfn )
        pclist = []
        cntlist = []
        for node in dom.getElementsByTagName('INSTANCE'):
            self._printStep = 100
            self._print_process()
            providerName = None
            moduleName = None
            className = None
            for subnode in node.getElementsByTagName('PROPERTY'):
                name = subnode.getAttributeNode('NAME').value
                #print subnode.getAttributeNode('CLASSORIGIN').value
                value = None
                for valnode in subnode.childNodes:
                    if ( valnode.nodeName == "VALUE" ):
                        for txtnode in valnode.childNodes:
                            value = txtnode.nodeValue
                if (name == "ProviderName"):
                    providerName = value
                if (name == "ProviderModuleName"):
                    moduleName = value
                if (name == "ClassName"):
                    className = value
            pclist.append("%s.%s" %(providerName,className))
            cntlist.append( (providerName,className) )
        self._printStep = 1
        self._print_process()
        dom.unlink()
        self._print_process()

        # Calc class count
        classCount = {}
        lastProviderName = ""
        cnt = 0
        classCnt = 0
        providerCnt = 0
        for (providerName, className) in cntlist:
            if (lastProviderName != providerName):
                classCount[lastProviderName] = cnt
                lastProviderName = providerName
                providerCnt = providerCnt + 1
                cnt = 0
            cnt = cnt + 1
            classCnt = classCnt + 1
        classCount[providerName] = cnt
        self._print_process()
                
        # Print the sorted provider-class list
        pclist.sort()
        self._print_end()
        lastProviderName = ""
        for pc in pclist:
            parts = pc.split(".")
            providerName = parts[0]
            className = parts[1]
            if (lastProviderName != providerName):
                lastProviderName = providerName
                print ""
                print providerName, "(%s classes)" % classCount[providerName]
            print "    %s" % className
        print ""
        print "-----------------------------------------------"
        print "Total providers = %d, total classes = %d" % (providerCnt, classCnt)


    def _handler_help( self, command, param, namespace ):
        if command != 'help':
            return
        self.cmds.optparser.print_usage()




wcmd    = WBEMCommandLine()
wclient = WBEMClient(wcmd)

#
# Execute command line input
#
if ( wcmd.interactive == False ):
    wmain   = WBEMHandler(wcmd, wclient)
    wmain._execute()
    sys.exit(0)

#
# Start Interactive python shell
#

cli     = wclient.conn

#
# Create some convenient global functions to reduce typing
#

def EnumerateInstanceNames(classname, namespace = None):
    """Enumerate the names of the instances of a CIM Class (including the
    names of any subclasses) in the target namespace."""

    return cli.EnumerateInstanceNames(classname, namespace = namespace)

def EnumerateInstances(classname, namespace = None, LocalOnly = True,
                       DeepInheritance = True, IncludeQualifiers = False,
                       IncludeClassOrigin = False):
    """Enumerate instances of a CIM Class (includeing the instances of
    any subclasses in the target namespace."""

    return cli.EnumerateInstances(classname, 
                                  namespace = namespace,
                                  DeepInheritance = DeepInheritance,
                                  IncludeQualifiers = IncludeQualifiers,
                                  IncludeClassOrigin = IncludeClassOrigin)


def GetInstance(instancename, LocalOnly = True, IncludeQualifiers = False,
                IncludeClassOrigin = False):
    """Return a single CIM instance corresponding to the instance name
    given."""

    return cli.GetInstance(instancename, 
                           LocalOnly = LocalOnly, 
                           IncludeQualifiers = IncludeQualifiers,
                           IncludeClassOrigin = IncludeClassOrigin)

def DeleteInstance(instancename):
    """Delete a single CIM instance."""

    return cli.DeleteInstance(instancename)

def ModifyInstance(*args, **kwargs):
    return cli.ModifyInstance(*args, **kwargs)

def CreateInstance(*args, **kwargs):
    return cli.CreateInstance(*args, **kwargs)

def InvokeMethod(*args, **kwargs):
    return cli.InvokeMethod(*args, **kwargs)

def AssociatorNames(*args, **kwargs):
    return cli.AssociatorNames(*args, **kwargs)

def Associators(*args, **kwargs):
    return cli.Associators(*args, **kwargs)

def ReferenceNames(*args, **kwargs):
    return cli.ReferenceNames(*args, **kwargs)

def References(*args, **kwargs):
    return cli.References(*args, **kwargs)

def EnumerateClassNames(*args, **kwargs):
    return cli.EnumerateClassNames(*args, **kwargs)

def EnumerateClasses(*args, **kwargs):
    return cli.EnumerateClasses(*args, **kwargs)

def GetClass(*args, **kwargs):
    return cli.GetClass(*args, **kwargs)

def DeleteClass(*args, **kwargs):
    return cli.DeleteClass(*args, **kwargs)

def ModifyClass(*args, **kwargs):
    return cli.ModifyClass(*args, **kwargs)

def CreateClass(*args, **kwargs):
    return cli.CreateClass(*args, **kwargs)

def EnumerateQualifiers(*args, **kwargs):
    return cli.EnumerateQualifiers(*args, **kwargs)

def GetQualifier(*args, **kwargs):
    return cli.GetQualifier(*args, **kwargs)

def SetQualifier(*args, **kwargs):
    return cli.SetQualifier(*args, **kwargs)

def DeleteQualifier(*args, **kwargs):
    return cli.DeleteQualifier(*args, **kwargs)

# Aliases for global functions above

ein = EnumerateInstanceNames
ei = EnumerateInstances
gi = GetInstance
di = DeleteInstance
mi = ModifyInstance
ci = CreateInstance

im = InvokeMethod

an = AssociatorNames
ao = Associators
rn = ReferenceNames
re = References

ecn = EnumerateClassNames
ec = EnumerateClasses
gc = GetClass
dc = DeleteClass
mc = ModifyClass
cc = CreateClass

eq = EnumerateQualifiers
gq = GetQualifier
sq = SetQualifier
dq = DeleteQualifier

# Some helper functions for indications

def MakeFilter(query, name = None):
    """Return a CIM_IndicationFilter instance with given query and name
    properties."""

    if name is None:
        name = 'wbemcli%d' % (random() * 1000)

    return CIMInstance(
        'CIM_IndicationFilter',
        {'Name': name,
         'Query': query,
         'QueryLanguage': 'WQL'},
        path = CIMInstanceName('CIM_IndicationFilter'))

def MakeDestination(url, name = None):
    """Return a CIM_ListenerDestinationCIMXML instance with given url and
    name properties."""

    if name is None:
        name = 'wbemcli%d' % (random() * 1000)

    return CIMInstance(
        'CIM_ListenerDestinationCIMXML',
        {'Name': name,
         'Destination': url},
        path = CIMInstanceName('CIM_ListenerDestinationCIMXML'))

def MakeSubscription(filter, destination):
    """Return a CIM_IndicationSubscription instance with given filter and
    handler properties."""
    
    return CIMInstance(
        'CIM_IndicationSubscription',
        {'Filter': filter,
         'Handler': destination},
        path = CIMInstanceName('CIM_IndicationSubscription'))

#
# Enter interactive console
#

def get_banner():
    
    result = ''

    # Note how we are connected

    result += 'Connected to %s' % cli.url
    if cli.creds is not None:
        result += ' as %s' % cli.creds[0]

    return result
        
# Read previous command line history

histfile = '%s/.wbemcli_history' % os.environ['HOME']

try:
    if have_readline:
        readline.read_history_file(histfile)
except IOError, arg:
    if arg[0] != errno.ENOENT:
        raise

# Interact

i = InteractiveConsole(globals())
i.interact(get_banner())

# Save command line history

if have_readline:
    readline.write_history_file(histfile)
